package org.myorg;

import java.io.Serializable;
import java.util.Random;

public class FGA2 {
	static int best_p;
	static double best_v;
	static FPeople2 best_people;

	public static void ga(int geneLength, float low, float high,
			int peopleNum, double p_cross,
			double p_mut, long i_num,Fc function) {
		FPeople2 my_p = new FPeople2(peopleNum,geneLength,low, high);
		FEvolution2 my_e = new FEvolution2(0.1, p_cross, p_mut, my_p, function);
		my_p.caculateFitness(function);
		best_people = new FPeople2(my_p);

		for (int i=0; i < i_num; i++) {

			double c_best = my_p.getPersons()[my_p.getBest(function)].fitness;
			double best = best_people.getPersons()[best_people.getBest(function)].fitness;
			if( c_best < best) {
				best_people=new FPeople2(my_p);
				best_p = my_p.getBest(function);

				/*				System.out.println(i+" FF the best individual is "+my_p.getPersons()[best_p].getGene()[0]);
				System.out.println(i+" FF the best value is "+my_p.getPersons()[best_p].getFitness());*/

			}


			//my_e.select();
			my_e.select(best_people);
			my_e.crossOver();
			my_e.mutation();
			my_p.caculateFitness(function);

		}
		//best_people=my_p;
		//best_p = my_p.getBest(function);

		System.out.println("FF the last best individual is "+my_p.getPersons()[best_p].getGene()[0]);
		System.out.println("FF the last best value is "+my_p.getPersons()[best_p].getFitness());

		System.out.println(" FF the best individual is "+best_people.getPersons()[best_p].getGene()[0]);
		System.out.println(" FF the best value is "+best_people.getPersons()[best_p].getFitness());
	}
	public static void ga(int geneLength, float low, float high,
			int peopleNum, double p_cross,
			double p_mut, long i_num,Fc function,
			long time) {
		long start_time = System.currentTimeMillis();
		FPeople2 my_p = new FPeople2(peopleNum,geneLength,low, high);
		FEvolution2 my_e = new FEvolution2(0.1, p_cross, p_mut, my_p, function);
		my_p.caculateFitness(function);
		best_people = new FPeople2(my_p);

		for (int i=0; i < i_num; i++) {

			double c_best = my_p.getPersons()[my_p.getBest(function)].fitness;
			double best = best_people.getPersons()[best_people.getBest(function)].fitness;
			if( c_best < best) {
				best_people=new FPeople2(my_p);
				best_p = my_p.getBest(function);

				/*				System.out.println(i+" FF the best individual is "+my_p.getPersons()[best_p].getGene()[0]);
				System.out.println(i+" FF the best value is "+my_p.getPersons()[best_p].getFitness());*/

			}
			if (System.currentTimeMillis() - start_time > time) {
				break;
			}

			//my_e.select();
			my_e.select(best_people);
			my_e.crossOver();
			my_e.mutation();
			my_p.caculateFitness(function);

		}
		//best_people=my_p;
		//best_p = my_p.getBest(function);

		/*		System.out.println("FF the last best individual is "+my_p.getPersons()[best_p].getGene()[0]);
		System.out.println("FF the last best value is "+my_p.getPersons()[best_p].getFitness());

		System.out.println(" FF the best individual is "+best_people.getPersons()[best_p].getGene()[0]);
		System.out.println(" FF the best value is "+best_people.getPersons()[best_p].getFitness());*/
	}

	public static String ga(int geneLength, float low, float high,
			int peopleNum, double p_cross,
			double p_mut, long i_num,Fc function,
			float[] data) {

		String res = "";

		long start_time = System.currentTimeMillis();
		FPeople2 my_p = new FPeople2(peopleNum,geneLength,low, high);
		FEvolution2 my_e = new FEvolution2(0.1, p_cross, p_mut, my_p, function);
		my_p.caculateFitness(function);
		best_people = new FPeople2(my_p);

		float best = Float.MAX_VALUE;
		boolean[] mark = new boolean[data.length];
		for (boolean bm : mark) {
			bm = false;
		}

		int count = 0;

		for (int i=0; i < i_num; i++) {


			/*if current best value are letter than global best value,
			 * replace global best value with current value
			 */
			float best_fitness = my_p.getPersons()[my_p.getBest(function)].fitness;
			if( best_fitness < best) {

				//best_people=new FPeople2(my_p);							
				//best = best_people.getPersons()[best_people.getBest(function)].fitness;
				best = best_fitness;

				if (count < data.length && !mark[count] && best < data[count] ) {
					res = res + "\t" + (System.currentTimeMillis() - start_time) +
					"\t" + i*peopleNum + "\t" + best;
					mark[count] = true;
					count++;
					if (count == data.length) {
						return res;
					}
				}
			}

			//my_e.select();
			my_e.select(best_people);
			my_e.crossOver();
			my_e.mutation();
			my_p.caculateFitness(function);

		}

		return res;
	}

}








